package com.lp.biz.member.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.pagehelper.PageHelper;
import com.lp.biz.identity.mapper.AdvisorMapper;
import com.lp.biz.identity.mapper.AdvisorMemberRelMapper;
import com.lp.biz.identity.mapper.BizIdentityMapper;
import com.lp.biz.identity.mapper.BizIdentityMemberRelMapper;
import com.lp.biz.identity.model.entity.Advisor;
import com.lp.biz.identity.model.entity.AdvisorMemberRel;
import com.lp.biz.identity.model.entity.BizIdentity;
import com.lp.biz.identity.model.entity.BizIdentityMemberRel;
import com.lp.biz.member.mapper.WithdrawalMapper;
import com.lp.biz.member.model.query.DistributorQuery;
import com.lp.biz.member.model.vo.DistributorList;
import com.lp.biz.member.model.vo.RateList;
import com.lp.biz.member.model.vo.WithdrawalHistories;
import com.lp.biz.member.service.WithdrawalService;
import com.lp.common.component.RedisService;
import com.lp.common.exception.BaseException;
import com.lp.common.exception.ErrorCodeEnum;
import com.lp.common.utils.CommonResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static com.lp.common.constant.AdvisorConstant.ADVISOR_TYPE_CODE;
import static com.lp.common.constant.CacheConstant.BIZ_USER_DETAIL_KEY;
import static com.lp.common.constant.IdentityConstant.IDENTITY_TYPE_CODE;
import static com.lp.common.utils.Tools.stripTrailingZeros;

/**
 * @program: backend
 * @description:
 * @author: Ke.Song
 * @since: 2024-06-29 20:57:40
 */
@Service
public class WithdrawalServiceImpl implements WithdrawalService {

    @Autowired
    private RedisService redis;

    @Autowired
    private AdvisorMapper advisorMapper;

    @Autowired
    private BizIdentityMapper identityMapper;

    @Autowired
    private WithdrawalMapper withdrawalMapper;

    @Autowired
    private AdvisorMemberRelMapper advisorMemberRelMapper;

    @Autowired
    private BizIdentityMemberRelMapper identityMemberRelMapper;

    @Override
    public CommonResult getDistributorList(DistributorQuery query) {
        PageHelper.startPage(query.getPage(), query.getSize());
        List<DistributorList> distributorList = withdrawalMapper.getDistributorList(query);
        for (DistributorList obj : distributorList) {
            obj.setAdvisorRate(stripTrailingZeros(obj.getAdvisorRate()));
            obj.setIdentityRate(stripTrailingZeros(obj.getIdentityRate()));
        }
        return CommonResult.restPage(distributorList);
    }

    @Override
    public CommonResult getHistories(DistributorQuery query) {
        PageHelper.startPage(query.getPage(), query.getSize());
        if (query.getStartAt() != null && query.getEndAt() != null && query.getStartAt().compareTo(query.getEndAt()) > 0) {
            throw new BaseException("时间筛选有误");
        }
        List<WithdrawalHistories> histories = withdrawalMapper.getHistories(query);
        for (WithdrawalHistories history : histories) {
            history.setAmount(stripTrailingZeros(history.getAmount()));
        }
        return CommonResult.restPage(histories);
    }

    @Override
    public CommonResult getRateList() {
        List<RateList> rateList = withdrawalMapper.getRateList();
        for (RateList rate : rateList) {
            rate.setRate(stripTrailingZeros(rate.getRate()));
        }
        return CommonResult.success(rateList);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void updateRate(RateList rate) {
        String code = rate.getCode();
        if (code.equals(IDENTITY_TYPE_CODE)) {
            BizIdentity identity = identityMapper.selectById(rate.getId());
            if (identity == null) {
                throw new BaseException(ErrorCodeEnum.PARAMS_ERROR);
            }
            identity.setRate(rate.getRate());
            identityMapper.updateById(identity);
            Set<Integer> collect = identityMemberRelMapper.selectList(new QueryWrapper<BizIdentityMemberRel>().lambda()
                    .eq(BizIdentityMemberRel::getBizIdentityId, identity.getId())).stream()
                    .map(BizIdentityMemberRel::getMemberId).collect(Collectors.toSet());
            if (!collect.isEmpty()) {
                updateRate(collect);
            }
        } else if (code.equals(ADVISOR_TYPE_CODE)) {
            if (rate.getCondition() == null || rate.getCondition() < 0) {
                throw new BaseException("升级条件输入错误");
            }
            Advisor advisor = advisorMapper.selectById(rate.getId());
            if (advisor == null) {
                throw new BaseException(ErrorCodeEnum.PARAMS_ERROR);
            }
            advisor.setRate(rate.getRate());
            advisor.setCondition(rate.getCondition());
            advisorMapper.updateById(advisor);
            Set<Integer> collect = advisorMemberRelMapper.selectList(new QueryWrapper<AdvisorMemberRel>().lambda()
                    .eq(AdvisorMemberRel::getAdvisorId, advisor.getId())).stream()
                    .map(AdvisorMemberRel::getMemberId).collect(Collectors.toSet());
            if (!collect.isEmpty()) {
                updateRate(collect);
            }
        } else {
            throw new BaseException(ErrorCodeEnum.PARAMS_ERROR);
        }
    }

    private void updateRate(Set<Integer> memberIds) {
        withdrawalMapper.updateRate(memberIds);
        redis.delete(memberIds.stream().map(o -> BIZ_USER_DETAIL_KEY + o).collect(Collectors.toSet()));
    }
}
